package com.wowangz.cms.syscore;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import org.apache.ibatis.session.SqlSession;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import com.wowangz.cms.syscore.utils.SpringUtil;

@SuppressWarnings("rawtypes")
public final class IssTransactionContainer {

	public static final Object getInstance(final Class classes, boolean operationAsOneTransaction) {
		Enhancer enhancer = new Enhancer();
		try {
			enhancer.setSuperclass(classes);
			enhancer.setCallback(new InvokeDelegation(operationAsOneTransaction, true));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return enhancer.create();
	}
}

/**
 * 拦截操作类
 *
 */
final class InvokeDelegation implements MethodInterceptor {

	@SuppressWarnings("unused")
	private InvokeDelegation() {
	}

	/**
	 * 所有操作是否作为一个事务的标志
	 */
	private boolean operationAsOneTransaction;
	
	private Object object = null;

	public InvokeDelegation(boolean operationAsOneTransaction, boolean usePublicDataSource) {
		this.operationAsOneTransaction = operationAsOneTransaction;
		
	}

	// 拦截方法
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		Object result = null;// 执行结果
		if(this.object == obj)
		{
			result = proxy.invokeSuper(obj, args);
			return result;
		}
		this.object = obj;
		SqlSessionContainer sqlSessionContainer = new SqlSessionContainer();
		SqlSession sqlSession = null;
		try {
			 sqlSession = sqlSessionContainer.getSqlSession();
			
			if (sqlSession == null) {
				sqlSession = getPublicSQLSession(!operationAsOneTransaction);
				sqlSessionContainer.putSqlSession(sqlSession);
			}
			else{
				sqlSession.getConnection().setAutoCommit(!operationAsOneTransaction);
			}
			
			
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		try {
			// 调用目标类的方法
			result = proxy.invokeSuper(obj, args);
			this.object = null;
			if (operationAsOneTransaction) {
				sqlSession.commit();
			}
		} catch (Exception e) {
			e.printStackTrace();
			try {
				if (operationAsOneTransaction) {
					sqlSession.rollback();
				}
			} catch (Exception e1) {
				// 事务回滚时发生异常
				e1.printStackTrace();
				throw e1;
			}
			throw e;// 业务代码执行时异常抛出
		} finally {
			
		}
		return result;
	}

	
	/**
	 * 获取通用数据连接
	 * 
	 * @param autocommit
	 * @return
	 */
	private static SqlSession getPublicSQLSession(boolean autocommit) {
		DriverManagerDataSource dataSource = (DriverManagerDataSource) SpringUtil.getBean("publicDataSource");
		SqlSession sqlsession = InitEnvironment.getSqlSessionFactory().openSession(dataSource, autocommit);
		return sqlsession;

	}

}